package com.yichi;

import android.annotation.SuppressLint;
import android.graphics.Rect;
import android.nfc.Tag;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;

import com.jeremyliao.liveeventbus.LiveEventBus;
import com.licheedev.modbus4android.ModbusCallback;
import com.licheedev.modbus4android.ModbusRespException;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.msg.ReadHoldingRegistersResponse;
import com.yichi.device_bean.BmsStatus;
import com.yichi.device_bean.PcbDataInfo;
import com.yichi.device_bean.PcbStatusInfo;
import com.yichi.device_bean.PlcInfo;
import com.yichi.global.EventDef;
import com.yichi.service.DeviceService;
import com.yichi.service.IccardService;
import com.yichi.service.PcbService;
import com.yichi.service.PlatformService;
import com.yichi.service.PlcService;
import com.yichi.util.ByteUtil;
import com.yichi.util.JsonUtil;
import com.yichi.util.StringUtil;
import com.yichi.util.ToastUtil;
import com.yichi.util.Utils;

import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;

public class AdminPlcTestFragment extends Fragment {

    private final static String TAG = "AdminPlcTestFragment";

    private TextView tv_iccard_info, tv_plc_info, tv_bms_status_info, tv_bms_data_info;
    private TextView button_move, button_open, button_read, button_read1, button_read2;
    private TextView button_shang, button_xia, button_zuo, button_you, button_qian, button_hou, button_back;
    private TextView button_read_iccard;
    private EditText et_store_src, et_store_tar;
    private TextView button_poweron, button_poweroff, button_read_bms_status, button_read_bms_data;
    private Spinner sp_recharge;
    private EditText et_speed;
    private TextView button_speed_x, button_speed_y, button_speed_z;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fg_plc_test, container, false);
        findView(view);
        setView();
        registerEvent();
        PlcService.inst.startQueryDeviceInfoTask();
        return view;
    }

    private void registerEvent() {
        LiveEventBus
                .get(EventDef.EVENT_PLC_INFO_QUERY_TASK, PlcInfo.class)
                .observe(this, new Observer<PlcInfo>() {
                    @Override
                    public void onChanged(PlcInfo plcInfo) {
                        if (plcInfo != null) {
                            renderPlcInfo(plcInfo);
                        }
                    }
                });
    }

    private void renderPlcInfo(PlcInfo plcInfo) {
        requireActivity().runOnUiThread(() -> {
            if (plcInfo == null) {
                tv_plc_info.setText("空值！！！");
            } else {
                StringBuilder sb = new StringBuilder();
                sb.append("心跳：" + plcInfo.getHeartbeat().toString() + "\n");
                sb.append("取出仓1门状态：" + plcInfo.getOutputDoorStatus1().toString() + "\n");
                sb.append("取出仓2门状态：" + plcInfo.getOutputDoorStatus2().toString() + "\n");
                sb.append("取出仓3门状态：" + plcInfo.getOutputDoorStatus3().toString() + "\n");
                sb.append("取出仓1电池状态：" + plcInfo.getOutputBatteryStatus1().toString() + "\n");
                sb.append("取出仓2电池状态：" + plcInfo.getOutputBatteryStatus2().toString() + "\n");
                sb.append("取出仓3电池状态：" + plcInfo.getOutputBatteryStatus3().toString() + "\n");
                sb.append("存入仓1门状态：" + plcInfo.getInputDoorStatus1().toString() + "\n");
                sb.append("存入仓2门状态：" + plcInfo.getInputDoorStatus2().toString() + "\n");
                sb.append("存入仓3门状态：" + plcInfo.getInputDoorStatus3().toString() + "\n");
                sb.append("电池移动状态：" + plcInfo.getBatteryMoveStatus().toString() + "\n");
                tv_plc_info.setText(sb.toString());
            }
        });
    }

    private void renderBmsStatus(PcbStatusInfo data) {
        requireActivity().runOnUiThread(() -> {
            if (data == null) {
                tv_bms_status_info.setText("空值！！！");
            } else {
                StringBuilder sb = new StringBuilder();
                sb.append("柜体烟雾状态：" + data.getDeviceYW().toString() + "\n");
                sb.append("柜体水位状态：" + data.getDeviceSW().toString() + "\n");
                sb.append("柜体温度状态：" + data.getDeviceWD().toString() + "\n");

                Map<String, BmsStatus> bmsStatusMap = data.getBmsStatusMap();
                for (String key : bmsStatusMap.keySet()) {
                    sb.append(String.format("%s号仓bms：%s\n", key, JsonUtil.toJSONString(bmsStatusMap.get(key))));
                }

                tv_bms_status_info.setText(sb.toString());
            }
        });
    }

    private void renderBmsData(PcbDataInfo data) {
        requireActivity().runOnUiThread(() -> {
            if (data == null) {
                tv_bms_data_info.setText("空值！！！");
            } else {
                StringBuilder sb = new StringBuilder();
                sb.append("柜体环境温度：" + data.getDeviceHJWD().toString() + "\n");
                sb.append("柜体供电电压：" + data.getDeviceGDDY().toString() + "\n");
                sb.append("柜体供电电流：" + data.getDeviceGDDL().toString() + "\n");
                sb.append("柜体有功功率：" + data.getDeviceYGGL().toString() + "\n");
                sb.append("柜体总电能：" + data.getDeviceZDN().toString() + "\n");

                for (Integer key : data.getBmsParamMap().keySet()) {
                    sb.append(String.format("%s号仓bms：%s\n", key, JsonUtil.toJSONString(data.getBmsParamMap().get(key))));
                }

                tv_bms_data_info.setText(sb.toString());
            }
        });
    }

    private void renderIccard(String[] arr) {
        requireActivity().runOnUiThread(() -> {
            if (arr == null) {
                tv_iccard_info.setText("");
            } else {
                String join = String.join(",", arr);
                tv_iccard_info.setText(join);
            }
        });

    }

    @SuppressLint("ClickableViewAccessibility")
    private void setView() {
        button_move.setOnClickListener(view -> {
            String src = et_store_src.getText().toString().trim();
            String tar = et_store_tar.getText().toString().trim();
            if (StringUtil.isEmpty(src)) {
                ToastUtil.show(requireContext(), "源不能为空");
                return;
            }
            if (StringUtil.isEmpty(tar)) {
                ToastUtil.show(requireContext(), "目的不能为空");
                return;
            }
            PlcService.inst.handleMoveBattery(Integer.valueOf(src), Integer.valueOf(tar));
            ToastUtil.show(requireContext(), "操作完成");
        });

        button_open.setOnClickListener(view -> {
            String src = et_store_src.getText().toString().trim();
            if (StringUtil.isEmpty(src)) {
                ToastUtil.show(requireContext(), "源不能为空");
                return;
            }
            PlcService.inst.handleOpenDoor(Integer.valueOf(src));
            ToastUtil.show(requireContext(), "操作完成");
        });

        button_read.setOnClickListener(view -> {
            String s = null;
            try {
                s = PlcService.inst.queryDeviceInfoStr();
                ToastUtil.show(requireContext(), "读到数据为：" + s);
            } catch (Exception e) {
                ToastUtil.show(requireContext(), "读数据错误：" + e.getMessage());
            }
        });

        button_read1.setOnClickListener(view -> {
            PlcService.inst.queryDeviceInfoCallback(new ModbusCallback<ReadHoldingRegistersResponse>() {
                @Override
                public void onSuccess(ReadHoldingRegistersResponse readHoldingRegistersResponse) {
                    byte[] data = readHoldingRegistersResponse.getData();
                    String s = ByteUtil.bytes2HexStr(data);
                    ToastUtil.show(requireContext(), "读到数据为：" + s);
                }

                @Override
                public void onFailure(Throwable tr) {
                    ToastUtil.show(requireContext(), "读取失败：" + tr.getMessage());
                }

                @Override
                public void onFinally() {
                }
            });
        });

        //循环读
        button_read2.setOnClickListener(view -> {
            button_read2.setEnabled(false);
            new Thread(() -> {
                while (true) {
                    PlcInfo plcInfo = PlcService.inst.queryDeviceInfo();
                    renderPlcInfo(plcInfo);

                    String[] strings = IccardService.inst.queryBatteryNo();
                    renderIccard(strings);

                    PcbStatusInfo pcbStatusInfo = PcbService.inst.queryStatusInfo(DeviceService.inst.rechargeStoreStartIndex, DeviceService.inst.rechargeStoreCount);
                    renderBmsStatus(pcbStatusInfo);

                    PcbDataInfo pcbDataInfo = PcbService.inst.queryDataInfo(DeviceService.inst.rechargeStoreStartIndex, DeviceService.inst.rechargeStoreCount);
                    renderBmsData(pcbDataInfo);

                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        Log.e(TAG, e.getMessage(), e);
                    }
                }
            }).start();
        });

        button_shang.setOnTouchListener((v, event) -> {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                ToastUtil.show(requireContext(), "按下了");
                //按下了
                PlcService.inst.handleMotor(1);
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
                ToastUtil.show(requireContext(), "抬起了");
                //松开了
                PlcService.inst.handleMotor(0);
            }
            return false;
        });
        button_xia.setOnTouchListener((v, event) -> {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                //按下了
                PlcService.inst.handleMotor(2);
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
                //松开了
                PlcService.inst.handleMotor(0);
            }
            return false;
        });
        button_zuo.setOnTouchListener((v, event) -> {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                //按下了
                PlcService.inst.handleMotor(3);
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
                //松开了
                PlcService.inst.handleMotor(0);
            }
            return false;
        });
        button_you.setOnTouchListener((v, event) -> {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                //按下了
                PlcService.inst.handleMotor(4);
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
                //松开了
                PlcService.inst.handleMotor(0);
            }
            return false;
        });
        button_qian.setOnTouchListener((v, event) -> {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                //按下了
                PlcService.inst.handleMotor(5);
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
                //松开了
                PlcService.inst.handleMotor(0);
            }
            return false;
        });
        button_hou.setOnTouchListener((v, event) -> {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                //按下了
                PlcService.inst.handleMotor(6);
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
                //松开了
                PlcService.inst.handleMotor(0);
            }
            return false;
        });
        button_back.setOnTouchListener((v, event) -> {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                //按下了
                PlcService.inst.handleMotor(7);
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
                //松开了
                PlcService.inst.handleMotor(0);
            }
            return false;
        });

        button_read_iccard.setOnClickListener(view -> {
            String[] strings = IccardService.inst.queryBatteryNo();
            renderIccard(strings);
        });

        button_poweron.setOnClickListener(view -> {
            String s = sp_recharge.getSelectedItem().toString();
            PcbService.inst.powerOn(Integer.valueOf(s));
            ToastUtil.show(requireContext(), "发送成功");
        });
        button_poweroff.setOnClickListener(view -> {
            String s = sp_recharge.getSelectedItem().toString();
            PcbService.inst.powerOff(Integer.valueOf(s));
            ToastUtil.show(requireContext(), "发送成功");
        });
        button_read_bms_status.setOnClickListener(view -> {
            try {
                PcbStatusInfo pcbStatusInfo = PcbService.inst.queryStatusInfoEx(DeviceService.inst.rechargeStoreStartIndex, DeviceService.inst.rechargeStoreCount);
                renderBmsStatus(pcbStatusInfo);
            } catch (Exception e) {
                requireActivity().runOnUiThread(() -> {
                    ToastUtil.show(requireContext(), "状态错误：" + e.getMessage());
                });
            }
        });
        button_read_bms_data.setOnClickListener(view -> {
            Executors.newSingleThreadExecutor().execute(() -> {
                PcbDataInfo pcbDataInfo = PcbService.inst.queryDataInfo(DeviceService.inst.rechargeStoreStartIndex, DeviceService.inst.rechargeStoreCount);
                renderBmsData(pcbDataInfo);
            });
        });
        button_speed_x.setOnClickListener(view -> {
            String string = et_speed.getText().toString();
            if (StringUtil.isEmpty(string)) {
                ToastUtil.show(requireContext(), "请输入0-100的速度");
                return;
            }
            Integer value = Integer.valueOf(string);
            if (value < 0 || value > 100) {
                ToastUtil.show(requireContext(), "请输入0-100的速度");
                return;
            }
            PlcService.inst.setSpeedX(value);
            ToastUtil.show(requireContext(), "Y发送成功");
        });
        button_speed_y.setOnClickListener(view -> {
            String string = et_speed.getText().toString();
            if (StringUtil.isEmpty(string)) {
                ToastUtil.show(requireContext(), "请输入0-100的速度");
                return;
            }
            Integer value = Integer.valueOf(string);
            if (value < 0 || value > 100) {
                ToastUtil.show(requireContext(), "请输入0-100的速度");
                return;
            }
            PlcService.inst.setSpeedY(value);
            ToastUtil.show(requireContext(), "Y发送成功");
        });
        button_speed_z.setOnClickListener(view -> {
            String string = et_speed.getText().toString();
            if (StringUtil.isEmpty(string)) {
                ToastUtil.show(requireContext(), "请输入0-100的速度");
                return;
            }
            Integer value = Integer.valueOf(string);
            if (value < 0 || value > 100) {
                ToastUtil.show(requireContext(), "请输入0-100的速度");
                return;
            }
            PlcService.inst.setSpeedZ(value);
            ToastUtil.show(requireContext(), "Y发送成功");
        });
    }

    private void findView(View view) {
        tv_iccard_info = view.findViewById(R.id.tv_iccard_info);
        tv_plc_info = view.findViewById(R.id.tv_plc_info);
        tv_bms_status_info = view.findViewById(R.id.tv_bms_status_info);
        tv_bms_data_info = view.findViewById(R.id.tv_bms_data_info);

        button_move = view.findViewById(R.id.button_move);
        button_open = view.findViewById(R.id.button_open);
        button_read = view.findViewById(R.id.button_read);
        button_read1 = view.findViewById(R.id.button_read1);
        button_read2 = view.findViewById(R.id.button_read2);
        et_store_src = view.findViewById(R.id.et_store_src);
        et_store_tar = view.findViewById(R.id.et_store_tar);

        button_shang = view.findViewById(R.id.button_shang);
        button_xia = view.findViewById(R.id.button_xia);
        button_zuo = view.findViewById(R.id.button_zuo);
        button_you = view.findViewById(R.id.button_you);
        button_qian = view.findViewById(R.id.button_qian);
        button_hou = view.findViewById(R.id.button_hou);
        button_back = view.findViewById(R.id.button_back);

        button_read_iccard = view.findViewById(R.id.button_read_iccard);
        sp_recharge = view.findViewById(R.id.sp_recharge);

        button_poweron = view.findViewById(R.id.button_poweron);
        button_poweroff = view.findViewById(R.id.button_poweroff);
        button_read_bms_status = view.findViewById(R.id.button_read_bms_status);
        button_read_bms_data = view.findViewById(R.id.button_read_bms_data);

        et_speed = view.findViewById(R.id.et_speed);
        button_speed_x = view.findViewById(R.id.button_speed_x);
        button_speed_y = view.findViewById(R.id.button_speed_y);
        button_speed_z = view.findViewById(R.id.button_speed_z);
    }

}
